/**
 * Character - 角色系统
 * 定义游戏中的角色数据模型和能力系统
 */

export enum CharacterAbilityType {
  SPEED = 'speed',
  JUMP = 'jump',
  SHIELD = 'shield',
  MAGNET = 'magnet',
  HEALTH = 'health',
  SLIDE = 'slide'
}

export interface CharacterAbility {
  type: CharacterAbilityType
  name: string
  description: string
  value: number
  duration?: number // 持续时间（毫秒），如果是被动能力则为undefined
  cooldown?: number // 冷却时间（毫秒）
}

export enum UnlockConditionType {
  SCORE = 'score',
  DISTANCE = 'distance',
  COINS = 'coins',
  GAMES_PLAYED = 'gamesPlayed',
  ACHIEVEMENTS = 'achievements',
  ALWAYS_UNLOCKED = 'alwaysUnlocked'
}

export interface UnlockCondition {
  type: UnlockConditionType
  value: number
  description: string
}

export interface CharacterStats {
  baseSpeed: number
  jumpForce: number
  health: number
  slideSpeed: number
  slideDuration: number
}

export interface Character {
  id: string
  name: string
  description: string
  sprite: string // 精灵图片路径或标识符
  rarity: 'common' | 'rare' | 'epic' | 'legendary'
  stats: CharacterStats
  abilities: CharacterAbility[]
  unlockCondition: UnlockCondition
  isUnlocked: boolean
  timesPlayed: number
  bestScore: number
  bestDistance: number
}

/**
 * 角色管理器
 */
export class CharacterManager {
  private characters: Map<string, Character> = new Map()
  private selectedCharacterId: string = ''

  constructor() {
    this.initializeDefaultCharacters()
  }

  /**
   * 初始化默认角色
   */
  private initializeDefaultCharacters(): void {
    const defaultCharacters: Character[] = [
      {
        id: 'runner',
        name: '跑者',
        description: '基础角色，平衡的能力适合新手',
        sprite: 'runner',
        rarity: 'common',
        stats: {
          baseSpeed: 200,
          jumpForce: 400,
          health: 3,
          slideSpeed: 150,
          slideDuration: 800
        },
        abilities: [
          {
            type: CharacterAbilityType.SPEED,
            name: '稳定奔跑',
            description: '保持稳定的跑步速度',
            value: 1.0
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.ALWAYS_UNLOCKED,
          value: 0,
          description: '默认解锁'
        },
        isUnlocked: true,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      },
      {
        id: 'speedster',
        name: '疾风',
        description: '移动速度更快，但生命值较低',
        sprite: 'speedster',
        rarity: 'rare',
        stats: {
          baseSpeed: 280,
          jumpForce: 380,
          health: 2,
          slideSpeed: 200,
          slideDuration: 600
        },
        abilities: [
          {
            type: CharacterAbilityType.SPEED,
            name: '疾风冲刺',
            description: '移动速度提升40%',
            value: 1.4
          },
          {
            type: CharacterAbilityType.SPEED,
            name: '快速恢复',
            description: '受伤后快速恢复移动速度',
            value: 1.2,
            duration: 3000
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.SCORE,
          value: 5000,
          description: '达到5000分解锁'
        },
        isUnlocked: false,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      },
      {
        id: 'jumper',
        name: '跳跃者',
        description: '跳跃能力超强，可以跳得更高更远',
        sprite: 'jumper',
        rarity: 'rare',
        stats: {
          baseSpeed: 180,
          jumpForce: 520,
          health: 3,
          slideSpeed: 130,
          slideDuration: 900
        },
        abilities: [
          {
            type: CharacterAbilityType.JUMP,
            name: '超级跳跃',
            description: '跳跃力提升30%',
            value: 1.3
          },
          {
            type: CharacterAbilityType.JUMP,
            name: '空中滑翔',
            description: '在空中可以短暂滑翔',
            value: 0.5, // 重力减少50%
            duration: 1000
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.DISTANCE,
          value: 2000,
          description: '跑步距离达到2000米解锁'
        },
        isUnlocked: false,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      },
      {
        id: 'tank',
        name: '坦克',
        description: '生命值更高，防御力强但速度较慢',
        sprite: 'tank',
        rarity: 'epic',
        stats: {
          baseSpeed: 160,
          jumpForce: 350,
          health: 5,
          slideSpeed: 120,
          slideDuration: 1200
        },
        abilities: [
          {
            type: CharacterAbilityType.HEALTH,
            name: '钢铁之躯',
            description: '最大生命值+2',
            value: 2
          },
          {
            type: CharacterAbilityType.SHIELD,
            name: '护盾冲撞',
            description: '受伤时获得短暂无敌',
            value: 1,
            duration: 2000
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.GAMES_PLAYED,
          value: 20,
          description: '游戏20次后解锁'
        },
        isUnlocked: false,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      },
      {
        id: 'collector',
        name: '收集者',
        description: '擅长收集金币和道具的专家',
        sprite: 'collector',
        rarity: 'epic',
        stats: {
          baseSpeed: 220,
          jumpForce: 400,
          health: 3,
          slideSpeed: 160,
          slideDuration: 700
        },
        abilities: [
          {
            type: CharacterAbilityType.MAGNET,
            name: '金币磁铁',
            description: '自动吸引附近的金币',
            value: 100, // 吸引范围像素
            duration: 5000
          },
          {
            type: CharacterAbilityType.MAGNET,
            name: '道具感应',
            description: '增加道具出现概率',
            value: 1.5 // 概率倍数
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.COINS,
          value: 1000,
          description: '收集1000金币解锁'
        },
        isUnlocked: false,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      },
      {
        id: 'ninja',
        name: '忍者',
        description: '滑铲大师，拥有最强的滑铲能力',
        sprite: 'ninja',
        rarity: 'legendary',
        stats: {
          baseSpeed: 240,
          jumpForce: 450,
          health: 2,
          slideSpeed: 300,
          slideDuration: 1500
        },
        abilities: [
          {
            type: CharacterAbilityType.SLIDE,
            name: '影分身滑铲',
            description: '滑铲距离和速度大幅提升',
            value: 2.0
          },
          {
            type: CharacterAbilityType.SLIDE,
            name: '滑铲无敌',
            description: '滑铲时免疫伤害',
            value: 1,
            duration: 1500
          }
        ],
        unlockCondition: {
          type: UnlockConditionType.ACHIEVEMENTS,
          value: 5,
          description: '解锁5个成就后获得'
        },
        isUnlocked: false,
        timesPlayed: 0,
        bestScore: 0,
        bestDistance: 0
      }
    ]

    defaultCharacters.forEach(character => {
      this.characters.set(character.id, character)
    })

    // 设置默认选中角色
    this.selectedCharacterId = 'runner'
  }

  /**
   * 获取所有角色
   */
  getAllCharacters(): Character[] {
    return Array.from(this.characters.values())
  }

  /**
   * 获取已解锁的角色
   */
  getUnlockedCharacters(): Character[] {
    return this.getAllCharacters().filter(character => character.isUnlocked)
  }

  /**
   * 根据稀有度获取角色
   */
  getCharactersByRarity(rarity: Character['rarity']): Character[] {
    return this.getAllCharacters().filter(character => character.rarity === rarity)
  }

  /**
   * 获取角色
   */
  getCharacter(id: string): Character | undefined {
    return this.characters.get(id)
  }

  /**
   * 获取当前选中的角色
   */
  getSelectedCharacter(): Character | undefined {
    return this.characters.get(this.selectedCharacterId)
  }

  /**
   * 选择角色
   */
  selectCharacter(id: string): boolean {
    const character = this.characters.get(id)
    if (character && character.isUnlocked) {
      this.selectedCharacterId = id
      return true
    }
    return false
  }

  /**
   * 解锁角色
   */
  unlockCharacter(id: string): boolean {
    const character = this.characters.get(id)
    if (character && !character.isUnlocked) {
      character.isUnlocked = true
      return true
    }
    return false
  }

  /**
   * 检查角色解锁条件
   */
  checkUnlockConditions(gameStats: {
    totalScore: number
    totalDistance: number
    totalCoins: number
    gamesPlayed: number
    achievementsUnlocked: number
  }): string[] {
    const newlyUnlocked: string[] = []

    this.characters.forEach(character => {
      if (!character.isUnlocked) {
        const condition = character.unlockCondition
        let shouldUnlock = false

        switch (condition.type) {
          case UnlockConditionType.SCORE:
            shouldUnlock = gameStats.totalScore >= condition.value
            break
          case UnlockConditionType.DISTANCE:
            shouldUnlock = gameStats.totalDistance >= condition.value
            break
          case UnlockConditionType.COINS:
            shouldUnlock = gameStats.totalCoins >= condition.value
            break
          case UnlockConditionType.GAMES_PLAYED:
            shouldUnlock = gameStats.gamesPlayed >= condition.value
            break
          case UnlockConditionType.ACHIEVEMENTS:
            shouldUnlock = gameStats.achievementsUnlocked >= condition.value
            break
          case UnlockConditionType.ALWAYS_UNLOCKED:
            shouldUnlock = true
            break
        }

        if (shouldUnlock) {
          character.isUnlocked = true
          newlyUnlocked.push(character.id)
        }
      }
    })

    return newlyUnlocked
  }

  /**
   * 更新角色统计
   */
  updateCharacterStats(id: string, score: number, distance: number): void {
    const character = this.characters.get(id)
    if (character) {
      character.timesPlayed++
      character.bestScore = Math.max(character.bestScore, score)
      character.bestDistance = Math.max(character.bestDistance, distance)
    }
  }

  /**
   * 获取角色能力修饰符
   */
  getCharacterModifiers(id: string): {
    speedMultiplier: number
    jumpMultiplier: number
    healthBonus: number
    slideSpeedMultiplier: number
    slideDurationMultiplier: number
    magnetRange: number
    shieldDuration: number
  } {
    const character = this.characters.get(id)
    if (!character) {
      return {
        speedMultiplier: 1,
        jumpMultiplier: 1,
        healthBonus: 0,
        slideSpeedMultiplier: 1,
        slideDurationMultiplier: 1,
        magnetRange: 0,
        shieldDuration: 0
      }
    }

    const modifiers = {
      speedMultiplier: 1,
      jumpMultiplier: 1,
      healthBonus: 0,
      slideSpeedMultiplier: 1,
      slideDurationMultiplier: 1,
      magnetRange: 0,
      shieldDuration: 0
    }

    character.abilities.forEach(ability => {
      switch (ability.type) {
        case CharacterAbilityType.SPEED:
          modifiers.speedMultiplier *= ability.value
          break
        case CharacterAbilityType.JUMP:
          modifiers.jumpMultiplier *= ability.value
          break
        case CharacterAbilityType.HEALTH:
          modifiers.healthBonus += ability.value
          break
        case CharacterAbilityType.SLIDE:
          modifiers.slideSpeedMultiplier *= ability.value
          modifiers.slideDurationMultiplier *= ability.value
          break
        case CharacterAbilityType.MAGNET:
          modifiers.magnetRange = Math.max(modifiers.magnetRange, ability.value)
          break
        case CharacterAbilityType.SHIELD:
          modifiers.shieldDuration = Math.max(modifiers.shieldDuration, ability.duration || 0)
          break
      }
    })

    return modifiers
  }

  /**
   * 序列化角色数据
   */
  serialize(): any {
    const data: any = {
      selectedCharacterId: this.selectedCharacterId,
      characters: {}
    }

    this.characters.forEach((character, id) => {
      data.characters[id] = {
        isUnlocked: character.isUnlocked,
        timesPlayed: character.timesPlayed,
        bestScore: character.bestScore,
        bestDistance: character.bestDistance
      }
    })

    return data
  }

  /**
   * 反序列化角色数据
   */
  deserialize(data: any): void {
    if (data.selectedCharacterId) {
      this.selectedCharacterId = data.selectedCharacterId
    }

    if (data.characters) {
      Object.entries(data.characters).forEach(([id, charData]: [string, any]) => {
        const character = this.characters.get(id)
        if (character) {
          character.isUnlocked = charData.isUnlocked || false
          character.timesPlayed = charData.timesPlayed || 0
          character.bestScore = charData.bestScore || 0
          character.bestDistance = charData.bestDistance || 0
        }
      })
    }
  }
}